const router = require('koa-router')()
const { exec } = require('../utils/exec')
const { SuccessModel, FailModel } = require('../utils/resModel')
const jwt = require('jsonwebtoken')
const { getPassword } = require('../utils/crypto')
const { secret_code } = require('../utils/index')
const { createCode } = require('../utils/svgCaptcha')
// const secret_code = '3411aQds_/.de' // 数字字母特殊字符

// jsonwebtoken
// token生成
// 密码等关键信息不要放在token中

// jwt.sign('生成token的信息','密钥字符串','token的有效时间')

// jwt数据结构 header.payload.Signature
// header: 描述 JWT 的元数据，
// payload: 用来存放实际需要传递的数据。
// Signature: Signature 部分是对前两部分的签名，防止数据篡改。

//  给访问路径添加前缀
router.prefix('/users')

/**
 * 1. 每个人在进入页面的时候，都会看到一个不同的验证码 （验证码和人无关）
 * table: code (codeId text => codeId和人是否有对应关系？)
 * table: users (id codeId => users表下的id是否有关系？)
 */

// 登陆校验码接口
router.get('/loginCode', async (ctx, next) => {
  // 1. 展示登陆页面 登陆页面自动调用这个接口，讲生成的数据展示给前端
  // 2. 前端拿上这个code值，访问后端这个接口，后端从数据库中取出text对比，如果对比成功，通过，让用户请求登陆接口
  // 3. 用户在登陆接口中进行比对
  try {
    // 生成校验码
    const info = createCode()
    // 任务一个人进入页面看到的验证码都可以存储起来，让用户在登录的时候，带上访问
    const sql = `insert into code (text) values (?)`
    const insertData = await exec(sql, [info.text])
    ctx.body = new SuccessModel({
      insertId: insertData.insertId,
      text: info.text,
      data: info.data,
    })
  } catch (err) {
    ctx.body = new FailModel('fail')
  }
})

// 登陆
router.post('/login', async (ctx, next) => {
  // 1. 拿参数
  const { username, password, text, codeId } = ctx.request.body
  try {
    //
    const codeSql = `select * from code where codeId = ? and text=?`
    const codeData = await exec(codeSql, [codeId, text])
    console.log('codeData:', codeData)
    if (codeData.length === 0) {
      ctx.body = new FailModel('验证码有错误，请重新输入')
      return
    }
    // 2. 数据库中查找
    const sql = `select * from users where username=? and password=?`
    const loginData = await exec(sql, [username, getPassword(password)])
    const token = jwt.sign(
      {
        id: loginData[0].id,
        username: loginData[0].username,
        gender: loginData[0].gender,
      },
      secret_code,
      { expiresIn: '24h' }
    )
    console.log('loginData:', loginData)
    ctx.body = new SuccessModel({ token })
  } catch (err) {
    ctx.body = new FailModel('登陆错误，请重新尝试', err)
  }
})

// 注册
router.post('/register', async (ctx, next) => {
  // 1. 拿参数
  const { username, password, nickname, gender, avatar } = ctx.request.body
  try {
    // 2. 数据库中查找
    const sql = `insert into users 
    (username, password, nickname, gender, avatar) 
    values (?,?,?,?,?)`
    const registerData = await exec(sql, [
      username,
      getPassword(password),
      nickname,
      gender,
      avatar,
    ])
    ctx.body = new SuccessModel(registerData)
  } catch (err) {
    ctx.body = new FailModel('注册失败，请重新尝试', err)
  }
})

router.get('/get-test', async (ctx, next) => {
  // 这个接口，需要用户带上token访问，这个就是用户接口权限，不带token,不能访问
  const { authorization } = ctx.request.headers
  try {
    // 校验
    const data = jwt.verify(authorization, secret_code)
    ctx.body = new SuccessModel({ msg: 'get-test' })
  } catch (err) {
    ctx.body = new FailModel(err)
  }
})

module.exports = router
